home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / FIREWALL.ZIP / FIREWALL.ASM < prev    next >
Assembly Source File  |  1996-06-03  |  10KB  |  182 lines

  1. ;FIREWALL.ASM by Tanjent, a.k.a. Austin Appleby
  2. ;
  3. ;Hello, hello, and welcome to the program that never ends... <grin>
  4. ;Well, until you hit a key, anyway... This is my own personal version
  5. ;of the now-overused flame algorithm, doctored up a bit and made to
  6. ;run in 320x200 because I'm too lazy to learn mode X programming. Besides,
  7. ;it looks a lot better without all its pixels doubled/quadrupled/whatever.
  8. ;This is my first program written in all Assembly, which I guess isn't bad
  9. ;since I've known this language a whole of, what, 2 weeks now? I've
  10. ;documented just about everything in there, because I remember how hard
  11. ;it was for me to read my first bit of code, even with documentation.
  12. ;So, better overkill than underkill . This whole mess has even been
  13. ;optimized a bit, though I imagine it can be sped up even more. This method
  14. ;is the best overall of the ones I've tried so far, nice clean code and
  15. ;fairly good speed (I could speed it up by unrolling the smooth loop 4
  16. ;steps and writing pixels in one nice stosd, but that doesn't save me
  17. ;enough clocks to merit the added code messiness.
  18. ;
  19. ;   For those poor souls among you who don't already know how a fire
  20. ;algorithm works, here's my very brief description - Set each pixel in the
  21. ;screen buffer equal to the average of some of its surrounding pixels, set
  22. ;the bottom line of the buffer to a random line of pixels, repeat ad
  23. ;nauseam. I'm using the following weighted average for my algorithm -
  24. ;
  25. ;            ...#... - Current pixel being computed
  26. ;            ...A...
  27. ;            ..BCD..
  28. ;            .......
  29. ;
  30. ;where the pixel being computed = ((16*A)+(14*C)+B+D)/32
  31. ;   This average gives nice, semi-round flames, and only takes a SHL
  32. ;and two SUBs more than a standard average (and it looks a lot nicer too).
  33. ;
  34. ;Any questions can be sent to me at appleby@mail.utexas.edu, and if you
  35. ;notice any ways to speed up this code PLEASE PLEASE tell me about them.
  36. ;I've gone through umpteen methods of rewriting this thing in trying to
  37. ;make it faster, and this is the fastest of the ones I've written so far.
  38. ;Farewell, and happy coding...
  39.  
  40.     DOSSEG
  41.     .MODEL SMALL
  42.     .STACK 200h
  43.     .DATA
  44.  
  45. INCLUDE rand.lst
  46. INCLUDE fire.pal
  47.     .CODE
  48.     .386
  49.     Ideal
  50.  
  51. PROC InitScrn NEAR          ;The Screen Initter. What a great name.
  52.                             ;I think I'll name my firstborn son Initter.
  53.                             ;It's just such a cool name, don't you think?
  54.     xor     eax,eax         ;Clear out those registers, just in case.
  55.     xor     di,di           ;
  56.     mov     bx,ss           ;Fetch the Stack Segment... Why, you ask?
  57.                             ;Well, the DOSSEG up at the top says that
  58.                             ;the segments in this program are going to be
  59.                             ;ordered with the stack segment last. So,
  60.                             ;we're fetching that segment address so we can
  61.                             ;set up a chunk of memory after it to use
  62.                             ;as a screen buffer.
  63.     add     bx,20h          ;Our stack is 200h bytes, so scoot up
  64.                             ;the segment index by enough so we're not
  65.                             ;overlapping it.
  66.     mov     cx,16240        ;We're using a buffer with 320*203 bytes,
  67.                             ;that's so we can stick the random dots
  68.                             ;offscreen and make it look a bit nicer.
  69.                             ;320*203 < 65536, so we'll still be able to get
  70.                             ;everything inside the same segment.
  71.     mov     es,bx           ;Make this our destination
  72.     rep     stosd           ;Fill it with a bunch of zeroes!
  73.     mov     ax,es           ;Swap that over to DS, since we'll need to
  74.     mov     ds,ax           ;read from it later.
  75.     mov     ax,0A000h       ;And put A000h, the screen segment, into ES.
  76.     mov     es,ax           ;
  77.     ret
  78. ENDP InitScrn
  79.  
  80. PROC Smooth NEAR            ;The Screen Smoother. It's slow, slow, slow.
  81.     mov     ecx,64000       ;64000 pixels to smooth
  82.     mov     edi,0           ;DS:EDI = current pixel
  83.     mov     esi,641         ;DS:ESI = Pixel that needs to be loaded
  84.                             ;the other two are kept in EAX
  85.     xor     eax,eax         ;Clear any stuff out of EAX before we begin
  86. smoothloop:
  87.     mov     bl,[ds:edi+320] ;Fetch the pixel that's a line below our current
  88.                             ;pixel, this is pixel A in the diagram
  89.     add     bx,ax           ;Add the pixel we saved from last time to BX
  90.                             ;This is pixel C in the diagram above
  91.     shl     bx,4            ;Multiply BX by 16 (A+C)*16=16*A+16*C
  92.     sub     bx,ax           ;Subtract AX twice, 16*A+16*C-C-C=
  93.     sub     bx,ax           ;                   16*A+14*C
  94.     ror     eax,16          ;Swap the high and low words of EAX
  95.     add     bx,ax           ;Add the value that was in the high word
  96.                             ;This is pixel B in the diagram. 
  97.     lodsb                   ;Load pixel D from memory
  98.     add     bx,ax           ;Add it to BX, now we have 16*A+14*C+B+D in BX
  99.     shr     bx,5            ;Divide BX by 32 to get an average
  100.     mov     [ds:edi],bl     ;Save the low byte into our buffer
  101.     inc     di              ;Increment our current pixel index
  102.     loop    smoothloop      ;Lather, rinse, repeat until done.
  103.     ret
  104. ENDP Smooth
  105.  
  106. PROC DumpScrn NEAR          ;The Screen Dumper.
  107.     mov     cx,16000        ;Very simple screen dump, DS=buffer
  108.     xor     di,di           ;& ES=A000h=screen. Gotta clear those 
  109.     xor     si,si           ;offsets first though...
  110.     rep     movsd           ;I like rep movsd. Do you?
  111.     ret
  112. ENDP DumpScrn
  113.  
  114. PROC RandLine NEAR          ;The Random Line Drawer.
  115.     push    ds              ;Save our segments, we're gonna screw
  116.     push    es              ;with em'
  117.     mov     ax,ds           ;Fetch DS, the buffer segment
  118.     add     ax,4000         ;Scoot it up by 4000*16=64000 bytes,
  119.                             ;so we point at a line that's offscreen.
  120.     mov     es,ax           ;Put it in our destination segment
  121.     mov     ax,seg Rand     ;Fetch the segment of our random table
  122.     mov     ds,ax           ;Make it our source segment
  123.     xor     ax,ax           ;Clear AX of those nasty residues
  124.     mov     al,[ebx]        ;set AL to a value in the random table
  125.                             ;with the index EBX
  126.     mov     si,ax           ;Make that random value our random table
  127.                             ;index so the random line jumps around
  128.     mov     di,10           ;Start writing at 10 pixels from the left edge
  129.     mov     cx,300          ;we'll be writing 300 pixels
  130.     rep     movsb           ;and copy those 300 pixels from the rand table
  131.     mov     si,ax           ;Reset our random table index
  132.     add     di,20           ;Scoot around so we're back under the first
  133.                             ;line of random pixels
  134.     mov     cx,300          ;write 300 more
  135.     rep     movsb           ;and copy them. Simple eh?
  136.     pop     es              ;Restore our original segments.
  137.     pop     ds              ;Weehoo weehoo.. i love comments.. <gag>
  138.     ret
  139. ENDP RandLine
  140.                
  141. START:                      ;Guess.
  142.     mov     al,0013h        ;Jump into mode 13h, 320x200x256 colors.
  143.     int     10h             ;using Int 10h
  144.     mov     dx,seg FirePal  ;Fetch our palette segment into DS
  145.     mov     ds,dx           ;
  146.     mov     si,offset FirePal   ;And get the offset too.
  147.     mov     dx,03c8h        ;Tell the vidcard at port 3c8 that we want to
  148.     xor     al,al           ;write the palette starting at color 0
  149.     out     dx,al           ;by dumping 0 to that port.
  150.     inc     dx              ;Now we want to dump to port 3c9.
  151.     mov     cx,256*3        ;We'll be dumping 256 colors * 3 values per
  152.                             ;color (R,G,B)
  153.     rep     outsb           ;Lather, rinse, repeat.
  154.  
  155.     call    InitScrn        ;Go set up our screen buffer.
  156.     xor     ebx,ebx         ;Clear out EBX, we'll be using it as a counter
  157.                             ;so we get a different line of random pixels
  158.                             ;from RandLine
  159.     looper:                 ;This is the loop that makes things boogie.
  160.     call    RandLine        ;Draw some random pixels in there
  161.     push    bx              ;Save our counter
  162.     call    Smooth          ;Smooth the buffer
  163.     mov     dx,3dah         ;Vertical Retrace Checking - port 3DAh
  164. V1: in      al,dx           ;I'm waiting on a baby VRT... won't my mommy
  165.     test    al,8            ;be so proud of me... <grin> All this bit
  166.     jnz     V1              ;does is check the video card to see
  167. V2: in      al,dx           ;if it's trying to update the screen,
  168.     test    al,8            ;and if it is we wait until it's done.
  169.     jz      V2              ;
  170.     call    DumpScrn        ;Dump it to the screen
  171.     pop     bx              ;Restore the counter
  172.     inc     bl              ;and increment it.
  173.     mov     ah,01           ;Test to see if some fool pressed a key
  174.     int     16h             ;with int 16h, subfunction 1.
  175.     jz      looper          ;If they didn't, keep going.
  176.     mov     ax,0003h        ;If they did, go back to text mode (3)
  177.     int     10h             ;with int 10h
  178.     mov     ax,4c00h        ;and return control to DOS. (whew!)
  179.     int     21h             ;with good ol' int 21.    
  180. END START
  181.  
  182.